﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Security.Cryptography.X509Certificates;
using System.Net;
using System.Net.Security;
using System.ServiceModel.Channels;
using System.ServiceModel;
using ConsoleApplication3.GemBoxx.BRP.Bijhouding;
using System.ServiceModel.Description;

namespace ConsoleApplication3
{
	class Program
	{
		static X509Certificate2 globCert = null;
		static void Cert()
		{
			var store = new X509Store(StoreLocation.CurrentUser);
			store.Open(OpenFlags.ReadOnly);
			X509Certificate2 cert = null;
			foreach (var findCert in store.Certificates)
			{
				if (findCert.Issuer == "CN=Staat der mGBA Root CA, L=Den Haag, S=Zuid-Holland, C=NL, E=support@modernodam.nl, OU=Modernodam, O=Staat der mGBA")
				{
					cert = findCert;
					globCert = cert;
				}
			}

			X509Certificate2 signcert = null;
			foreach (var findCert in store.Certificates)
			{
				if (findCert.Issuer.Contains("Whitebox"))
				{
					signcert = findCert;
				}
			}
		
		}

		static void TestBevraging()
		{
			var wc = new GemBoxx.BRP.OpvragenPersoonPortTypeClient();


			wc.ClientCredentials.SupportInteractive = true;

			GemBoxx.BRP.OpvragenPersoonVraag vrg = new GemBoxx.BRP.OpvragenPersoonVraag
			{
				abonnementId = 364,
				afzenderId = 364,
				bsn = "123456789",
				id = 1,
				tijdstipVerzonden = DateTime.Now
			};

			var opr = new GemBoxx.BRP.OpvragenPersoonRequest(vrg);
			var antw = wc.OpvragenPersoon(opr);
			Console.WriteLine(antw.OpvragenPersoonAntwoord.persoon[0].bsn);
		}

		static void TestBijhoudingMulti()
		{
			EndpointAddress serviceEndpoint =
			   new EndpointAddress(new Uri("https://brp-proeftuin.modernodam.nl/brp/services/bijhouding"));

			CustomBinding binding = new CustomBinding();

			TransportSecurityBindingElement securityBE = SecurityBindingElement.CreateCertificateOverTransportBindingElement(
				MessageSecurityVersion.WSSecurity11WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10);

//            AsymmetricSecurityBindingElement securityBE =
//                SecurityBindingElement.CreateMutualCertificateDuplexBindingElement(
//                MessageSecurityVersion.
//WSSecurity11WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10);

			// Add a custom IdentityVerifier because the service uses two certificates 
			// (one for signing and one for encryption) and an endpoint identity that 
			// contains a single identity claim.
			securityBE.LocalClientSettings.IdentityVerifier = new MyIdentityVerifier();
			securityBE.EnableUnsecuredResponse = true;
			securityBE.AllowInsecureTransport = false;
			securityBE.IncludeTimestamp = true;
			securityBE.LocalClientSettings.MaxClockSkew = new TimeSpan(0, 10, 0);

			binding.Elements.Add(securityBE);

			//CompositeDuplexBindingElement compositeDuplex =
			//    new CompositeDuplexBindingElement();
			//compositeDuplex.ClientBaseAddress = new Uri("http://localhost:6061/client");
			//binding.Elements.Add(compositeDuplex);

			binding.Elements.Add(new TextMessageEncodingBindingElement { MessageVersion = MessageVersion.Soap11   } );

			binding.Elements.Add(new HttpsTransportBindingElement { RequireClientCertificate = true, DecompressionEnabled=true } );

			using (ChannelFactory<BijhoudingPortType> factory =
				new ChannelFactory<BijhoudingPortType>(binding, serviceEndpoint))
			{
				MyClientCredentials credentials = new MyClientCredentials();
				// SetupCertificates(credentials);
				var xs = new X509Store(StoreName.My, StoreLocation.CurrentUser);

				xs.Open(OpenFlags.ReadOnly);

				credentials.ClientCertificate.Certificate = xs.Certificates.Find(X509FindType.FindBySubjectName, "client2", true)[0];
				credentials.ClientEncryptingCertificate = xs.Certificates.Find(X509FindType.FindBySubjectDistinguishedName, "CN=Whitebox, L=Den Haag, S=Zuid-Holland, C=NL, E=support@modernodam.nl, OU=BRP, O=BZK", true)[0];
				credentials.ClientSigningCertificate = xs.Certificates.Find(X509FindType.FindBySubjectDistinguishedName, "CN=Whitebox, L=Den Haag, S=Zuid-Holland, C=NL, E=support@modernodam.nl, OU=BRP, O=BZK", true)[0];

				credentials.ServiceCertificate.DefaultCertificate = xs.Certificates.Find(X509FindType.FindBySubjectDistinguishedName, "CN=WhiteboxServer", true)[0]; 
				credentials.ServiceSigningCertificate = xs.Certificates.Find(X509FindType.FindBySubjectDistinguishedName, "CN=WhiteboxServer", true)[0];
				credentials.ServiceEncryptingCertificate = xs.Certificates.Find(X509FindType.FindBySubjectDistinguishedName, "CN=WhiteboxServer", true)[0];

				factory.Endpoint.Behaviors.Remove(typeof(ClientCredentials));
				factory.Endpoint.Behaviors.Add(credentials);
		
				BijhoudingPortType channel = factory.CreateChannel();



				var geboorteRequest = new GemBoxx.BRP.Bijhouding.inschrijvingGeboorteRequest();
				var bijhouding = new GemBoxx.BRP.Bijhouding.Afstamming_InschrijvingAangifteGeboorte_Bijhouding();
				geboorteRequest.afstamming_InschrijvingAangifteGeboorte_Bijhouding = bijhouding;
				bijhouding.stuurgegevens = new GemBoxx.BRP.Bijhouding.Groep_BerichtStuurgegevens[1];
				bijhouding.stuurgegevens[0] = new GemBoxx.BRP.Bijhouding.Groep_BerichtStuurgegevens();
				bijhouding.stuurgegevens[0].applicatie = new GemBoxx.BRP.Bijhouding.Applicatienaam { Value = "gemboxx" };
				bijhouding.stuurgegevens[0].organisatie = new GemBoxx.BRP.Bijhouding.Organisatienaam { Value = "0364" };
				bijhouding.stuurgegevens[0].referentienummer = new GemBoxx.BRP.Bijhouding.Sleutelwaardetekst { Value = Guid.NewGuid().ToString("N") };


				bijhouding.acties = new GemBoxx.BRP.Bijhouding.Container_BerichtActies[1];
				bijhouding.acties[0] = new GemBoxx.BRP.Bijhouding.Container_BerichtActies();
				bijhouding.acties[0].inschrijvingGeboorte = new GemBoxx.BRP.Bijhouding.View_InschrijvingGeboorte[1];
				bijhouding.acties[0].inschrijvingGeboorte[0] = new GemBoxx.BRP.Bijhouding.View_InschrijvingGeboorte();
				bijhouding.acties[0].inschrijvingGeboorte[0].persoon = new GemBoxx.BRP.Bijhouding.Objecttype_Persoon[1];
				bijhouding.acties[0].inschrijvingGeboorte[0].persoon[0] = new GemBoxx.BRP.Bijhouding.Objecttype_Persoon();
				bijhouding.acties[0].inschrijvingGeboorte[0].persoon[0].bijhoudingsgemeente = new GemBoxx.BRP.Bijhouding.Groep_PersoonBijhoudingsgemeente[1];
				bijhouding.acties[0].inschrijvingGeboorte[0].tijdstipOntlening = new GemBoxx.BRP.Bijhouding.DatumTijd { Value = "20120521141000" };
				bijhouding.acties[0].inschrijvingGeboorte[0].datumAanvangGeldigheid = new GemBoxx.BRP.Bijhouding.Datum { Value = "20120521" };

				bijhouding.acties[0].inschrijvingGeboorte[0].familierechtelijkeBetrekking = new GemBoxx.BRP.Bijhouding.View_FamilierechtelijkeBetrekking[1];
				bijhouding.acties[0].inschrijvingGeboorte[0].familierechtelijkeBetrekking[0] = new GemBoxx.BRP.Bijhouding.View_FamilierechtelijkeBetrekking();
				//bijhouding.acties[0].inschrijvingGeboorte[0].familierechtelijkeBetrekking[0].datumAanvang = new GemBoxx.BRP.Bijhouding.Datum { Value = "20110521" };
				//bijhouding.acties[0].inschrijvingGeboorte[0].familierechtelijkeBetrekking[0].gemeenteAanvangCode = new GemBoxx.BRP.Bijhouding.Gemeentecode { Value = "0346" };
				//bijhouding.acties[0].inschrijvingGeboorte[0].familierechtelijkeBetrekking[0].landAanvangCode = new GemBoxx.BRP.Bijhouding.Landcode { Value = "0000" };
				////bijhouding.acties[0].inschrijvingGeboorte[0].familierechtelijkeBetrekking[0].tijdstipRegistratie = new GemBoxx.BRP.Bijhouding.DatumTijd { Value = "20120521" };
				//bijhouding.acties[0].inschrijvingGeboorte[0].familierechtelijkeBetrekking[0].woonplaatsAanvangCode = new GemBoxx.BRP.Bijhouding.Woonplaatscode { Value = "0346" };

				bijhouding.acties[0].inschrijvingGeboorte[0].familierechtelijkeBetrekking[0].betrokkenheden = new GemBoxx.BRP.Bijhouding.Container_RelatieBetrokkenheden[1];
				bijhouding.acties[0].inschrijvingGeboorte[0].familierechtelijkeBetrekking[0].betrokkenheden[0] = new GemBoxx.BRP.Bijhouding.Container_RelatieBetrokkenheden();
				bijhouding.acties[0].inschrijvingGeboorte[0].familierechtelijkeBetrekking[0].betrokkenheden[0].kind = new GemBoxx.BRP.Bijhouding.View_Kind[1];
				bijhouding.acties[0].inschrijvingGeboorte[0].familierechtelijkeBetrekking[0].betrokkenheden[0].kind[0] = new GemBoxx.BRP.Bijhouding.View_Kind();
				bijhouding.acties[0].inschrijvingGeboorte[0].familierechtelijkeBetrekking[0].betrokkenheden[0].kind[0].persoon = new GemBoxx.BRP.Bijhouding.Objecttype_Persoon();
				
				bijhouding.acties[0].inschrijvingGeboorte[0].familierechtelijkeBetrekking[0].betrokkenheden[0].ouder = new GemBoxx.BRP.Bijhouding.View_Ouder[2];
				bijhouding.acties[0].inschrijvingGeboorte[0].familierechtelijkeBetrekking[0].betrokkenheden[0].ouder[0] = new GemBoxx.BRP.Bijhouding.View_Ouder();
				bijhouding.acties[0].inschrijvingGeboorte[0].familierechtelijkeBetrekking[0].betrokkenheden[0].ouder[0].persoon = new GemBoxx.BRP.Bijhouding.Objecttype_Persoon();
				bijhouding.acties[0].inschrijvingGeboorte[0].familierechtelijkeBetrekking[0].betrokkenheden[0].ouder[0].ouderschap = new Groep_BetrokkenheidOuderschap[1];
				bijhouding.acties[0].inschrijvingGeboorte[0].familierechtelijkeBetrekking[0].betrokkenheden[0].ouder[0].ouderschap[0] = new Groep_BetrokkenheidOuderschap();
				bijhouding.acties[0].inschrijvingGeboorte[0].familierechtelijkeBetrekking[0].betrokkenheden[0].ouder[0].ouderschap[0].tijdstipRegistratie = new DatumTijd { Value = "20110521" };

				bijhouding.acties[0].inschrijvingGeboorte[0].familierechtelijkeBetrekking[0].betrokkenheden[0].ouder[1] = new GemBoxx.BRP.Bijhouding.View_Ouder();

				bijhouding.acties[0].inschrijvingGeboorte[0].familierechtelijkeBetrekking[0].betrokkenheden[0].ouder[1].persoon = new GemBoxx.BRP.Bijhouding.Objecttype_Persoon();

				
				
				Console.WriteLine(channel.inschrijvingGeboorte(geboorteRequest));
				
			}


		}
		static void TestBijhouding()
		{
			BasicHttpBinding bbinding = new BasicHttpBinding(BasicHttpSecurityMode.TransportWithMessageCredential);

			BindingElementCollection bec = bbinding.CreateBindingElements();


			TransportSecurityBindingElement tsp = bec.Find<TransportSecurityBindingElement>();
			tsp.MessageSecurityVersion = MessageSecurityVersion.WSSecurity10WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10;
			

			HttpsTransportBindingElement httpsBinding = bec.Find<HttpsTransportBindingElement>();


			TextMessageEncodingBindingElement encoding = bec.Find<TextMessageEncodingBindingElement>();

			httpsBinding.RequireClientCertificate =			true;
		

			CustomBinding cub = new CustomBinding(tsp, encoding, httpsBinding);



			var epa = new EndpointAddress("https://brp-proeftuin.modernodam.nl/brp/services/bijhouding");
			var bijhoudingClient = new GemBoxx.BRP.Bijhouding.BijhoudingPortTypeClient( cub, epa);
			
			bijhoudingClient.ClientCredentials.ClientCertificate.Certificate = globCert;

		

			var geboorteRequest = new GemBoxx.BRP.Bijhouding.inschrijvingGeboorteRequest();
			var bijhouding = new GemBoxx.BRP.Bijhouding.Afstamming_InschrijvingAangifteGeboorte_Bijhouding();
			geboorteRequest.afstamming_InschrijvingAangifteGeboorte_Bijhouding = bijhouding;
			bijhouding.stuurgegevens = new GemBoxx.BRP.Bijhouding.Groep_BerichtStuurgegevens[1];
			bijhouding.stuurgegevens[0] = new GemBoxx.BRP.Bijhouding.Groep_BerichtStuurgegevens();
			bijhouding.stuurgegevens[0].applicatie = new GemBoxx.BRP.Bijhouding.Applicatienaam { Value = "gemboxx"};
			bijhouding.stuurgegevens[0].organisatie = new GemBoxx.BRP.Bijhouding.Organisatienaam { Value = "0364" };
			bijhouding.stuurgegevens[0].referentienummer = new GemBoxx.BRP.Bijhouding.Sleutelwaardetekst { Value = Guid.NewGuid().ToString("N") };

			
			bijhouding.acties = new GemBoxx.BRP.Bijhouding.Container_BerichtActies[1];
			bijhouding.acties[0] = new GemBoxx.BRP.Bijhouding.Container_BerichtActies();
			bijhouding.acties[0].inschrijvingGeboorte = new GemBoxx.BRP.Bijhouding.View_InschrijvingGeboorte[1];
			bijhouding.acties[0].inschrijvingGeboorte[0] = new GemBoxx.BRP.Bijhouding.View_InschrijvingGeboorte();
			bijhouding.acties[0].inschrijvingGeboorte[0].persoon = new GemBoxx.BRP.Bijhouding.Objecttype_Persoon[1];
			bijhouding.acties[0].inschrijvingGeboorte[0].persoon[0] = new GemBoxx.BRP.Bijhouding.Objecttype_Persoon();
			bijhouding.acties[0].inschrijvingGeboorte[0].persoon[0].bijhoudingsgemeente = new GemBoxx.BRP.Bijhouding.Groep_PersoonBijhoudingsgemeente[1];
			bijhouding.acties[0].inschrijvingGeboorte[0].tijdstipOntlening = new GemBoxx.BRP.Bijhouding.DatumTijd { Value = "20120521141000" };
			bijhouding.acties[0].inschrijvingGeboorte[0].datumAanvangGeldigheid = new GemBoxx.BRP.Bijhouding.Datum { Value = "20120521" };

			bijhouding.acties[0].inschrijvingGeboorte[0].familierechtelijkeBetrekking = new GemBoxx.BRP.Bijhouding.View_FamilierechtelijkeBetrekking[1];
			bijhouding.acties[0].inschrijvingGeboorte[0].familierechtelijkeBetrekking[0] = new GemBoxx.BRP.Bijhouding.View_FamilierechtelijkeBetrekking();
			bijhouding.acties[0].inschrijvingGeboorte[0].familierechtelijkeBetrekking[0].datumAanvang = new GemBoxx.BRP.Bijhouding.Datum { Value = "20110521" };
			bijhouding.acties[0].inschrijvingGeboorte[0].familierechtelijkeBetrekking[0].gemeenteAanvangCode = new GemBoxx.BRP.Bijhouding.Gemeentecode { Value = "0346" };
			bijhouding.acties[0].inschrijvingGeboorte[0].familierechtelijkeBetrekking[0].landAanvangCode = new GemBoxx.BRP.Bijhouding.Landcode { Value = "0000" };
			bijhouding.acties[0].inschrijvingGeboorte[0].familierechtelijkeBetrekking[0].tijdstipRegistratie = new GemBoxx.BRP.Bijhouding.DatumTijd { Value = "20120521143900" };
			bijhouding.acties[0].inschrijvingGeboorte[0].familierechtelijkeBetrekking[0].woonplaatsAanvangCode = new GemBoxx.BRP.Bijhouding.Woonplaatscode { Value = "0346" };

			bijhouding.acties[0].inschrijvingGeboorte[0].familierechtelijkeBetrekking[0].betrokkenheden = new GemBoxx.BRP.Bijhouding.Container_RelatieBetrokkenheden[1];
			bijhouding.acties[0].inschrijvingGeboorte[0].familierechtelijkeBetrekking[0].betrokkenheden[0] = new GemBoxx.BRP.Bijhouding.Container_RelatieBetrokkenheden();
			bijhouding.acties[0].inschrijvingGeboorte[0].familierechtelijkeBetrekking[0].betrokkenheden[0].kind = new GemBoxx.BRP.Bijhouding.View_Kind[1];
			bijhouding.acties[0].inschrijvingGeboorte[0].familierechtelijkeBetrekking[0].betrokkenheden[0].kind[0] = new GemBoxx.BRP.Bijhouding.View_Kind();
			bijhouding.acties[0].inschrijvingGeboorte[0].familierechtelijkeBetrekking[0].betrokkenheden[0].kind[0].persoon = new GemBoxx.BRP.Bijhouding.Objecttype_Persoon();

			bijhouding.acties[0].inschrijvingGeboorte[0].familierechtelijkeBetrekking[0].betrokkenheden[0].ouder = new GemBoxx.BRP.Bijhouding.View_Ouder[2];
			bijhouding.acties[0].inschrijvingGeboorte[0].familierechtelijkeBetrekking[0].betrokkenheden[0].ouder[0] = new GemBoxx.BRP.Bijhouding.View_Ouder();
			bijhouding.acties[0].inschrijvingGeboorte[0].familierechtelijkeBetrekking[0].betrokkenheden[0].ouder[0].persoon = new GemBoxx.BRP.Bijhouding.Objecttype_Persoon();

			bijhouding.acties[0].inschrijvingGeboorte[0].familierechtelijkeBetrekking[0].betrokkenheden[0].ouder[1] = new GemBoxx.BRP.Bijhouding.View_Ouder();

			bijhouding.acties[0].inschrijvingGeboorte[0].familierechtelijkeBetrekking[0].betrokkenheden[0].ouder[1].persoon = new GemBoxx.BRP.Bijhouding.Objecttype_Persoon();




			var result = bijhoudingClient.inschrijvingGeboorte(geboorteRequest);


			Console.WriteLine(result.afstamming_InschrijvingAangifteGeboorte_BijhoudingResponse.ToString());
		}

		static void Main(string[] args)
		{
			ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls;

			ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(OnValidationCallback);
			// ServicePointManager.ServerCertificateValidationCallback = new LocalCertificateSelectionCallback(OnValidationCallback);
			

			Cert();

			//TestBevraging();

			// TestBijhouding();

			TestBijhoudingMulti();
			
		}

		public static bool OnValidationCallback(object sender, X509Certificate cert, X509Chain chain, SslPolicyErrors errors)
		{
			return true;
		}

	}
}
